package com.yomob.recommend.service;

import com.yomob.recommend.entity.AdEntity;
import org.apache.spark.SparkConf;
import org.apache.spark.SparkContext;
import org.apache.spark.mllib.recommendation.MatrixFactorizationModel;
import org.apache.spark.mllib.recommendation.Rating;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class AdService {
    private SparkConf conf;
    private MatrixFactorizationModel model;
    private SparkContext sc;
    private HashMap<Integer, String> userInfo = new HashMap<Integer, String>();
    private HashMap<Integer, String> adInfo = new HashMap<Integer, String>();

    private HashMap<String, Integer> userIndex = new HashMap<String, Integer>();
    private HashMap<String, Integer> adInIndex = new HashMap<String, Integer>();

    private HashMap<Integer, List<Integer>> useAds = new HashMap<>();

    /**
     * 模型加载
     */
    public AdService() {
        conf = new SparkConf().setMaster("local").setAppName("mongo");
        sc = new SparkContext(conf);
        //加载本地模型数据
        model = MatrixFactorizationModel.load(sc, "/Users/qifei/work/recommendModel");
        String[] ad = (String[]) sc.textFile("/Users/qifei/work/ad", 1).collect();
        String[] user = (String[]) sc.textFile("/Users/qifei/work/user", 1).collect();
        String[] ratings = (String[]) sc.textFile("/Users/qifei/work/ratings", 1).collect();
//        model = MatrixFactorizationModel.load(sc, modelPath);
//        String[] ad = (String[]) sc.textFile(outPutPath+"/ad", 1).collect();
//        String[] user = (String[]) sc.textFile(outPutPath+"/user", 1).collect();
//        String[] ratings = (String[]) sc.textFile(outPutPath+"/ratings", 1).collect();
        for (int i = 0; i < ad.length; i++) {
            String kv[] = ad[i].substring(1, ad[i].length() - 1).split(",");
            adInfo.put(Integer.valueOf(kv[0]), kv[1]);
            adInIndex.put(kv[1], Integer.valueOf(kv[0]));
        }
        for (int i = 0; i < user.length; i++) {
            String kv[] = user[i].substring(1, user[i].length() - 1).split(",");
            userInfo.put(Integer.valueOf(kv[0]), kv[1]);
            userIndex.put(kv[1], Integer.valueOf(kv[0]));
        }
        for (int i = 0; i < ratings.length; i++) {
            String kv[] = ratings[i].substring("rating(".length(), ratings[i].length() - 1).split(",");
            List<Integer> ads = null;
            if (useAds.containsKey(kv[0])) {
                ads = useAds.get(kv[0]);
            } else {
                ads = new ArrayList<>();
            }
            ads.add(Integer.valueOf(kv[1]));
            useAds.put(Integer.valueOf(kv[0]), ads);
        }
    }

    /**
     * 数值转换，获取推荐列表，过滤已看过的ad，再转换，返回recommend
     *
     * @param id
     * @return
     */
    public AdEntity recommendByDeviceId(String id) {
        //to Int
        if (!userIndex.containsKey(id)) {
            //todo
            return null;
        }
        //get user click Id num
        int userId = userIndex.get(id);
        //set recommend num
        int clickAdsNum = useAds.get(userId).size();

        int recommendSize = clickAdsNum + 5;
        //filter
        //Int adId to String ,get ad real Id
        Rating[] ratings = model.recommendProducts(userId, recommendSize);
        HashMap<String, Double> recommends = new HashMap<>();
        for (int i = 0; i < ratings.length; i++) {
            int pId = ratings[i].product();
            if (!useAds.get(userId).contains(pId)) {
                recommends.put(adInfo.get(pId) + "", ratings[i].rating());
            }
        }
        AdEntity adEntity = new AdEntity();
        adEntity.setDeviceId(id);
        adEntity.setRecommends(recommends);
        if (recommends.size() == 0) {
            return null;
        }
        return adEntity;
    }
}
